<template>
  <div class="main-content">
    <div class="view-title">
      <!--      <h2>版本管理</h2>-->
    </div>
    <div class="table-bar">
      <tool-bar
        :cond.sync="filterBy"
        @create="handleCreate"
        @refresh="refresh"
        @search="handleSearch"
      />
    </div>
    <div class="table-content">
      <el-table
        ref="multipleTable"
        v-loading="loading"
        :data="tableData"
        border
        class="table"
        max-height="700"
        header-cell-class-name="table-header"
        tooltip-effect="light"
        :default-sort="defaultSortConf"
        @sort-change="changeSort"
      >
        <el-table-column type="selection" width="50" align="center" />
        <el-table-column type="index" width="50" align="center" label="序号" />
        <template v-for="item in tableColumn">
          <el-table-column
            v-if="item.type === 'popover'"
            :key="item.index"
            :prop="item.index"
            :width="item.width"
            :label="item.label"
            :formatter="item.formatter"
            :show-overflow-tooltip="item.tip"
          >
            <template slot-scope="scope">
              <el-popover trigger="click" placement="top">
                <el-table
                  border
                  :data="parseCond(scope.row.cond)"
                  max-height="300px"
                  :span-method="objectSpanMethod"
                >
                  <el-table-column width="150" property="field" label="字段名(field)" />
                  <el-table-column
                    width="300"
                    property="fieldV"
                    label="字段值(value)"
                    :show-overflow-tooltip="true"
                  />
                </el-table>
                <el-tag slot="reference" size="medium" class="name-wrapper" style="cursor:pointer">
                  {{ condShowV }}
                </el-tag>
              </el-popover>
            </template>
          </el-table-column>
          <el-table-column
            v-if="item.type === 'common'"
            :key="item.index"
            :prop="item.index"
            :width="item.width"
            :label="item.label"
            :sortable="item.sortable"
            :formatter="item.formatter"
            :show-overflow-tooltip="item.tip"
          />
          <el-table-column
            v-if="item.type === 'tag'"
            :key="item.index"
            :prop="item.index"
            :width="item.width"
            :label="item.label"
            :sortable="item.sortable"
            :formatter="item.formatter"
            :show-overflow-tooltip="item.tip"
          >
            <template slot-scope="scope">
              <div class="el-tag-group">
                <el-tag
                  v-for="itemData in getTagData(scope.row)"
                  :key="itemData.key"
                  :type="itemData.type"
                  :color="itemData.color"
                  effect="dark"
                  size="small"
                >
                  {{ itemData.val }}
                </el-tag>
              </div>
            </template>
          </el-table-column>
        </template>
        <el-table-column label="操作" width="120" align="center">
          <template slot-scope="scope">
            <el-dropdown trigger="click" @command="handleOperate">
              <el-button type="primary" size="mini">
                操作列表<i class="el-icon-arrow-down el-icon--right" />
              </el-button>
              <el-dropdown-menu slot="dropdown">
                <template v-for="(value, key) in operateMap">
                  <el-dropdown-item
                    :key="key"
                    :command="{command: key, scope: scope}"
                    :icon="typeof value.icon === 'function' ? value.icon(scope.row) : value.icon"
                    :disabled="value.disabled(scope.row)"
                  >{{ typeof value.label === 'function' ? value.label(scope.row) : value.label }}</el-dropdown-item>
                </template>
              </el-dropdown-menu>
            </el-dropdown>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <div class="table-footer">
      <el-pagination
        :current-page="pageInfo.pageNum"
        :page-sizes="pageInfo.sizeItems"
        :page-size="pageInfo.pageSize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="pageInfo.totalSize"
        :page-count="pageInfo.totalPages"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>

    <div id="dialog_content">
      <create-dialog
        :mode.sync="planMode"
        :visible.sync="dialogVisible"
        :type="dialogType"
        @callback="loadData"
      />
    </div>
  </div>
</template>
<script>
import fota from '../../api/fota'
import { formatTimeToStr } from '../../utils/index'
import CreateDialog from './createDialog'
import ToolBar from './toolBar'
import apiConst from '../../common/js/apiConst'

export default {
  components: { CreateDialog, ToolBar },
  data() {
    return {
      loading: false,
      tableColumn: [],
      tableData: [],
      products: [],
      versionList: [],
      servers: [],
      pageInfo: {},
      delList: [],
      dialogVisible: false,
      dialogType: '',
      sortConf: {},
      defaultSortConf: { prop: 'createTime', order: 'descending' },
      filterBy: {},
      planMode: undefined,
      operateMap: {
        ctl_status: { label: (row) => row.status ? '挂起' : '激活', icon: (row) => row.status ? 'el-icon-sunrise' : 'el-icon-moon-night', handle: this.handleUpdateStatus, disabled: this.hasAuth },
        ctl_edit: { label: '编辑', icon: 'el-icon-edit', handle: this.handleEdit, disabled: this.hasAuth },
        ctl_copy: { label: '复制', icon: 'el-icon-copy-document', handle: this.handleCopy, disabled: () => false },
        ctl_delete: { label: '删除', icon: 'el-icon-delete', handle: this.handleDelete, disabled: this.hasAuth }
      }
    }
  },
  created() {
    this.initTableBaseInfo()
  },
  mounted() {
    this.loadData()
  },
  methods: {
    handleOperate: function({ command, scope }) {
      this.operateMap[command].handle(scope)
    },
    hasAuth: function(row) {
      const cond = row.cond ? JSON.parse(row.cond) : {}
      return (cond.type ? parseInt(cond.type) : 0) === 1 && this.$store.getters.hasAuth(apiConst.ROLE.TEST)
    },
    handleCopy({ row }) {
      this.dialogType = 'copy'
      this.queryItemById(row.id, false)
      this.dialogVisible = true
    },
    handleEdit({ row }) {
      this.dialogType = 'update'
      this.queryItemById(row.id)
      this.dialogVisible = true
    },
    queryItemById(id, forUpdate = true) {
      fota.queryPlanById(id).then(resp => {
        const plan = resp.data
        const cond = JSON.parse(plan.cond)
        this.planMode = {
          name: plan.name,
          product: plan.product,
          srcV: plan.srcV.split(','),
          dstV: plan.dstV,
          createTime: plan.createTime,
          updateTime: plan.updateTime,
          description: plan.description,
          status: `${plan.status}`,
          updateType: `${cond.updateType}`,
          timeEnable: cond.timeRange !== undefined && cond.timeRange.length === 2,
          timeRange: cond.timeRange || [],
          type: `${cond.type || ''}`,
          otherSrcCond: cond.otherSrcCond,
          otherDstCond: cond.otherDstCond,
          imeiType: this.getImeiType(cond.imei),
          imei: cond.imei
        }
        if (forUpdate) {
          this.planMode.id = plan.id
        }
      }, () => {
        fota.notifyError(`当前升级计划查询失败！`)
      })
    },
    getImeiType(imei) {
      if (imei === undefined || imei === '') {
        return 'close'
      } else if (imei.startsWith('(') || imei.startsWith('[')) {
        return 'range'
      } else if (imei.indexOf(',') !== -1 || imei.indexOf('，') !== -1) {
        return 'multi_v'
      } else {
        return 'equal'
      }
    },
    handleSearch() {
      this.loadData()
    },
    handleCreate() {
      this.dialogType = 'create'
      this.dialogVisible = true
    },
    handleUpdateStatus({ row }) {
      this.loading = true
      const self = this
      const newStatus = row.status === 1 ? 0 : 1
      fota.updatePlan({ id: row.id, status: newStatus }).then(() => {
        row.status = newStatus
        fota.notifySuccess('升级计划状态更新成功！')
        self.refresh()
        self.loading = false
      }, () => {
        fota.notifyError(`升级计划状态更新失败！`)
        self.loading = false
      })
    },
    handleDelete({ $index, row }) {
      console.log($index)
      this.$refs.multipleTable.clearSelection()
      this.delList.push(row)
      this.delAllSelection()
    },
    delAllSelection() {
      const tmp = this.delList.concat(this.multipleSelection || [])
      if (tmp.length === 0) {
        return
      }
      this.$confirm('此操作将永久删除版本是否继续？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        let param = ''
        this.delList = tmp
        for (let i = 0; i < this.delList.length; i++) {
          param += this.delList[i].id
          if (i !== this.delList.length - 1) {
            param += ','
          }
        }
        this.loading = true
        this.deleteModel(param)
        this.delList = []
      }).catch(err => {
        console.log(`未知异常: ${JSON.stringify(err)}`)
      })
    },
    deleteModel: function(param) {
      this.loading = true
      const self = this
      fota.deletePlan(param).then(() => {
        fota.notifySuccess('升级计划删除成功！')
        self.initTableData()
      }, () => {
        fota.notifyError(`升级计划删除失败！`)
        self.loading = false
      })
    },
    initTableBaseInfo() {
      this.tableColumn = [
        { index: 'name', label: '名称', tip: true, type: 'common', sortable: 'custom' },
        { index: 'product', label: '产品', tip: true, type: 'common', sortable: 'custom' },
        { index: 'srcV', label: '当前版本', tip: true, type: 'common' },
        { index: 'dstV', label: '目标版本', tip: true, type: 'common', sortable: 'custom' },
        { index: 'cond', label: '其他条件', tip: true, type: 'popover' },
        { index: 'createTime', label: '创建时间', width: 160, formatter: this.timeFormatter, type: 'common', sortable: 'custom' },
        { index: 'description', label: '描述', tip: true, type: 'common' },
        { index: 'status', label: '状态', width: 110, tip: true, type: 'tag',
          tagMapping: { 1: { label: '激活', type: 'success' }, 0: { label: '挂起', type: 'info' }}
        }
      ]
      this.pageInfo = {
        pageNum: 1,
        pageSize: 10,
        totalPages: 1,
        totalSize: 1,
        sizeItems: [10, 20, 50, 100, 200, 500, 1000]
      }
      this.sortConf = this.defaultSortConf
    },
    handleSizeChange: function(newSize) {
      this.pageInfo.pageSize = newSize
      this.loading = true
      this.initTableData()
    },
    handleCurrentChange: function(pageNum) {
      this.pageInfo.pageNum = pageNum
      this.loading = true
      this.initTableData()
    },
    changeSort: function({ prop, order }) {
      if (order === null) {
        this.sortConf = this.defaultSortConf
      } else {
        this.sortConf = { prop: prop, order: order }
      }
      this.loadData()
    },
    getOrderByCond() {
      const columnMapping = { srcV: 'src_v', dstV: 'dst_v', createTime: 'create_time' }
      const orderMapper = { descending: 'desc', ascending: 'asc' }
      return `status desc, ${(columnMapping[this.sortConf.prop] || this.sortConf.prop)} ${orderMapper[this.sortConf.order]}`
    },
    initTableData: function() {
      const self = this
      const param = {
        pageNum: this.pageInfo.pageNum,
        pageSize: this.pageInfo.pageSize,
        orderBy: this.getOrderByCond(),
        filterBy: this.filterBy
      }
      fota.queryPlanInfo(param).then(res => {
        self.tableData = res.data.data
        self.pageInfo.totalPages = res.data.totalPages
        self.pageInfo.totalSize = res.data.totalSize
        self.loading = false
      }, () => {
        fota.notifyError(`升级计划查询失败！`)
        self.loading = false
      })
    },
    refresh() {
      this.filterBy = { timeRange: [] }
      this.loadData()
    },
    loadData() {
      this.loading = true
      this.initTableData()
    },
    timeFormatter: function(row) {
      return formatTimeToStr(row.createTime)
    },
    parseCond: function(cond) {
      this.condShowV = '点击查看'
      let condition = {}
      try {
        condition = JSON.parse(cond)
        let rst = [
          { field: 'owner', fieldV: condition.owner || '-' },
          this.getType('type', condition),
          this.getUpdateType('updateType', condition),
          this.getTimeRange('timeRange', condition),
          this.getOtherCond('otherSrcCond', condition),
          this.getOtherCond('otherDstCond', condition),
          ...this.getImeiCond('imei', condition)
        ]
        rst = rst.filter(item => item !== undefined && item.field !== undefined)
        if (rst.length === 0) {
          this.condShowV = '无条件'
          return [{ field: '条件', fieldV: cond }]
        }
        return rst
      } catch (e) {
        console.log(`cond parse may be error: ${e}`)
        this.condShowV = cond === '{}' ? '无条件' : '解析异常'
        return [{ field: '条件', fieldV: cond }]
      }
    },
    getType: function(key, condition) {
      const val = condition[key] || '0'
      const keyName = '计划类型'
      const mapping = { '0': '未知计划', '1': '测试计划', '2': '前线计划' }
      return { field: keyName, fieldV: mapping[val] }
    },
    getOtherCond: function(key, condition) {
      const keyName = key === 'otherSrcCond' ? '当前版本标识' : '目标版本标识'
      const cond = condition[key]
      if (cond === undefined) {
        return {}
      }
      const condObj = JSON.parse(cond)
      const rst = Object.entries(condObj).map(item => {
        return `${item[0]}:${item[1]}`
      })
      return { field: keyName, fieldV: rst.join(';') }
    },
    getTimeRange: function(key, condition) {
      const keyName = '生效时间'
      const timeRange = condition[key]
      if (timeRange === undefined) {
        return {}
      }
      switch (timeRange.length) {
        case 0:
          return {}
        case 2:
          return {
            field: keyName,
            fieldV: `${formatTimeToStr(timeRange[0], 'HH:mm:ss')} - ${formatTimeToStr(timeRange[1], 'HH:mm:ss')}`
          }
        default:
          return { field: keyName, fieldV: timeRange }
      }
    },
    getUpdateType: function(key, condition) {
      const val = condition[key]
      const keyName = '升级方式'
      const mapping = { '0': '无限制', '1': '手动', '2': '自动' }
      return { field: keyName, fieldV: mapping[val] }
    },
    getImeiCond: function(key, condition) {
      const val = condition[key]
      if (val === undefined) {
        return []
      }
      // [asd,dsas]
      if (/^[\[(][\w\d]*[,，][\w\d]*[)\]]$/g.test(val)) {
        return [
          { field: key, fieldV: val }
        ]
      } else {
        const vals = val.split(/[,，]/)
        let first = true
        return vals.map(function(item) {
          if (first) {
            first = false
            return { field: key, fieldV: item, rowSpan: vals.length }
          }
          return { field: key, fieldV: item, rowSpan: 0 }
        })
      }
    },
    objectSpanMethod({ row, columnIndex }) {
      if (columnIndex === 0) {
        if (row.rowSpan !== undefined) {
          return { rowspan: row.rowSpan, colspan: 1 }
        } else {
          return { rowspan: 1, colspan: 1 }
        }
      }
    },
    getTagData(row) {
      let cond = {}
      const statusMap = { 1: { type: 'success', val: '激活' }, 0: { type: 'info', val: '挂起' }}
      const typeMap = { 2: { type: 'warning', val: '前线' }, 1: { type: 'danger', val: '测试' }, 0: { type: 'unknown', val: '未知' }}
      const tmp = [
        {
          key: `status_${row.id}_${row.status}`,
          type: statusMap[row.status] ? statusMap[row.status].type : statusMap[0].type,
          val: statusMap[row.status] ? statusMap[row.status].val : statusMap[0].val
        }
      ]

      try {
        cond = JSON.parse(row.cond)
        const typeObj = typeMap[cond.type] ? typeMap[cond.type] : typeMap[0]
        tmp.push({
          key: `type_${row.id}_${cond.type}`,
          type: typeObj.type,
          color: typeObj.color,
          val: typeObj.val
        })
      } catch (e) {
        console.log(`cond parse may be error: ${e}`)
      }
      return tmp
    }
  }
}
</script>

<style scoped>
    .main-content {
        padding: 16px;
    }

    .table-bar {
        margin: 0 8px 8px 0;
    }

    .table-footer {
        float: right;
        margin-top: 8px;
    }

    /* tag group style */
    .el-tag-group {
      display: inline-block;
      vertical-align: middle;
    }

    .el-tag-group > .el-tag:first-child {
      border-top-right-radius: 0;
      border-bottom-right-radius: 0;
    }
    .el-tag-group > .el-tag:last-child {
      border-top-left-radius: 0;
      border-bottom-left-radius: 0;
    }

    .el-tag-group > .el-tag:not(:last-child) {
      margin-right: -1px;
    }

    .el-tag-group > .el-tag:not(:first-child):not(:last-child) {
      border-radius: 0;
    }
    .el-tag--dark.el-tag--unknown {
      background-color: #1ac2ff;
      border-color: #1ac2ff;
      color: white;
    }
</style>
